﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace ElfTyping.General
{
    public class Camera
    {
        SpriteBatch spriteBatch;
        Texture2D whiteTexture;

        public Camera(SpriteBatch _spriteBatch)
        {
            spriteBatch = _spriteBatch;
            whiteTexture = TypingGame.Game().Content.Load<Texture2D>(@"Textures\White");
        }

        public void DrawRectangle(Rectangle rectangle, Color color)
        {
            spriteBatch.Draw(whiteTexture, rectangle, color);
        }

        public void DrawRectangle(Rectangle rectangle, Texture2D texture)
        {
            spriteBatch.Draw(texture, rectangle, Color.White);
        }

        public void DrawRectangleUV(Rectangle drawRectangle, Texture2D texture, Rectangle uvRectangle, Color color, bool flippedHorizontally)
        {
            if (flippedHorizontally)
            {
                spriteBatch.Draw(texture, drawRectangle, uvRectangle, color, 0, Vector2.Zero, SpriteEffects.FlipHorizontally, 0);
            }
            else
            {
                spriteBatch.Draw(texture, drawRectangle, uvRectangle, color);
            }
        }

        public TextDrawer MakeText(string text)
        {
            return new TextDrawer(spriteBatch, text);
        }

        public class TextDrawer
        {
            public static SpriteFont TimesNewRomanFont = TypingGame.Game().Content.Load<SpriteFont>(@"Fonts\TimesNewRoman");
            public static SpriteFont TimesNewRomanBigFont = TypingGame.Game().Content.Load<SpriteFont>(@"Fonts\TimesNewRomanBig");
            public static SpriteFont TimesNewRomanVeryBigFont = TypingGame.Game().Content.Load<SpriteFont>(@"Fonts\TimesNewRomanVeryBig");

            public string Text { get; set; }
            public SpriteFont Font { get; set; }

            private const byte ShadowBlacknessLimit = 40;
            private Color _color { get; set; }
            public Color Color { 
                get { return _color; }
                set
                {
                    _color = value;
                    ShadowColor = (value.R + value.G + value.B < ShadowBlacknessLimit) ? Color.White : Color.Black;
                }
            }
            private Color ShadowColor { get; set; }
            private bool ShouldDrawShadow { get; set; }

            public int SecondaryColorStartIndex { get; private set; }
            private Color _secondaryColor { get; set; }
            public Color SecondaryColor { 
                get { return _secondaryColor; }
                private set
                {
                    _secondaryColor = value;
                    SecondaryShadowColor = (value.R + value.G + value.B < ShadowBlacknessLimit) ? Color.White : Color.Black;
                }
            }
            private Color SecondaryShadowColor { get; set; }


            public Vector2 CenteredPosition { get; set; }
            public bool ShouldCenterPosition { get; set; }

            public Vector2 BottomLeftPosition { get; set; } 

            private SpriteBatch SpriteBatch { get; set; }

            public TextDrawer(SpriteBatch spriteBatch, string text)
            {
                Text = text;
                Font = TimesNewRomanFont;
                Color = Color.Black;
                SecondaryColor = Color.Black;
                SecondaryColorStartIndex = -1;
                BottomLeftPosition = new Vector2();
                CenteredPosition = new Vector2();
                ShouldCenterPosition = false;
                ShouldDrawShadow = true;

                SpriteBatch = spriteBatch;
            }

            public TextDrawer WithFont(SpriteFont font)
            {
                Font = font;
                return this;
            }

            public TextDrawer WithCenteredPosition(Point position)
            {
                return WithCenteredPosition(new Vector2(position.X, position.Y));
            }

            public TextDrawer WithCenteredPosition(Vector2 position)
            {
                CenteredPosition = position;
                ShouldCenterPosition = true;
                return this;
            }

            public TextDrawer WithCenteredPosition(float x, float y)
            {
                return WithCenteredPosition(new Vector2(x, y));
            }

            public TextDrawer WithTopLeftPosition(Vector2 position)
            {
                BottomLeftPosition = position;
                ShouldCenterPosition = false;
                return this;
            }

            public TextDrawer WithTopLeftPosition(float x, float y)
            {
                return WithTopLeftPosition(new Vector2(x, y));
            }

            public TextDrawer WithColor(Color color)
            {
                Color = color;
                return this;
            }

            public TextDrawer WithSecondaryColor(Color color, int startingAt)
            {
                SecondaryColor = color;
                SecondaryColorStartIndex = startingAt;
                return this;
            }

            public TextDrawer WithoutShadows()
            {
                ShouldDrawShadow = false;
                return this;
            }

            public Point Draw()
            {
                Vector2 textLength = Font.MeasureString(Text);
                if (ShouldCenterPosition)
                {
                    BottomLeftPosition = new Vector2(CenteredPosition.X - textLength.X/2f, CenteredPosition.Y - textLength.Y/2f);
                }

                if (SecondaryColorStartIndex != -1)
                {
                    string firstPart = Text.Substring(0, SecondaryColorStartIndex);
                    string secondPart = Text.Substring(SecondaryColorStartIndex);
                    Vector2 firstLength = Font.MeasureString(firstPart);
                    Vector2 secondPosition = new Vector2(BottomLeftPosition.X + firstLength.X, BottomLeftPosition.Y);

                    DrawBasicText(SpriteBatch, Font, firstPart, BottomLeftPosition, Color, ShadowColor, ShouldDrawShadow);
                    DrawBasicText(SpriteBatch, Font, secondPart, secondPosition, SecondaryColor, SecondaryShadowColor, ShouldDrawShadow);
                }
                else
                {
                    DrawBasicText(SpriteBatch, Font, Text, BottomLeftPosition, Color, ShadowColor, ShouldDrawShadow);
                }
                return new Point();
            }

            private static void DrawBasicText(SpriteBatch spriteBatch, SpriteFont font, string text, Vector2 position, Color color, Color shadowColor, bool includeShadow)
            {
                if (includeShadow)
                {
                    Vector2 shadowPosition = new Vector2(position.X - 1, position.Y - 1);
                    spriteBatch.DrawString(font, text, shadowPosition, shadowColor);
                }
                spriteBatch.DrawString(font, text, position, color);
            }
        }
    }    
}
